package cn.melonlib.specials.auth.comp.service;

import cn.hutool.core.codec.Base64;
import cn.melonlib.cores.commons.comp.service.impl.WorkerBasicService;
import cn.melonlib.cores.jpa.model.bean.impl.DefaultQuery;
import cn.melonlib.security.encryption.anno.Encrypt;
import cn.melonlib.security.encryption.anno.SecurityService;
import cn.melonlib.security.encryption.comp.enc.EncryptionService;
import cn.melonlib.security.encryption.enums.EncTarget;
import cn.melonlib.specials.auth.model.entity.Account;
import cn.melonlib.specials.auth.model.entity.AccountPassword;
import cn.melonlib.specials.auth.model.entity.AccountPasswordRecord;
import cn.melonlib.specials.auth.model.enums.PasswordStrength;
import org.intellij.lang.annotations.Language;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

@Service
@SecurityService
public class AccountManagerService extends WorkerBasicService<Account> {


    @Resource
    private EncryptionService encryptionService;
//    @Decrypt(target = EncTarget.STORE)
//    public User encVal(@Encrypt(target = EncTarget.STORE,paths = {"code","realName"}) User val){
//        System.out.println(val.getNickName());
//        System.out.println(val.getCode());
//        System.out.println(val.getRealName());
//        return val;
//    }

//    @WorkerStore
//    @WorkerComment("创建账户")
    public Account createAccount(Account account,@Encrypt(target = EncTarget.STORE) String password){
        @Language("HQL") String hql="from Account where account=?1 and tenantId=?2";
        List<Account> accounts=dao.<List<Account>,DefaultQuery>search(new DefaultQuery(hql,List.of(account.getAccount(),account.getTenantId()))).getResult();
        if(accounts.size()>0){
            return null;
        }
        Account result=dao.save(account).getResult();
        dao.flush();
        this.modifyPassword(result,password);
        return result;
    }

    public Boolean modifyPassword( String account, String tenant, String validPassword, String password) throws Exception{
        @Language("HQL") String hql="from Account where account=?1 and tenantId=?2";
        List<Account> accounts=dao.<List<Account>,DefaultQuery>search(new DefaultQuery(hql,List.of(account,tenant))).getResult();
        if(accounts.isEmpty()){
            return false;
        }
        @Language("HQL") String validPasswords="from AccountPassword where account=?1";
        List<AccountPassword> passwords=this.dao.<List<AccountPassword>,DefaultQuery>search(new DefaultQuery(validPasswords, List.of(accounts.get(0)))).getResult();
        if(passwords.isEmpty()){
            return false;
        }
        String pwd=new String(encryptionService.storeDec(Base64.decode(passwords.get(0).getPassword())).getVal(), StandardCharsets.UTF_8);
        if(!Objects.equals(validPassword,pwd)){
            this.modifyPassword(accounts.get(0),password);
            return true;
        }else{
            return false;
        }


    }

    public Boolean modifyPassword(Account account,@Encrypt(target = EncTarget.STORE) String password){
        String passwordhql="delete from AccountPassword where account=?1";
        dao.updateQl(passwordhql,List.of(account));
        String pwdRecord="update AccountPasswordRecord set scrap=true,scrapDateTime=?1 where account=?2 and scrap=false";
        dao.updateQl(pwdRecord,List.of(System.currentTimeMillis(),account));
        AccountPassword accountPassword=new AccountPassword();
        accountPassword.setAccount(account);
        accountPassword.setPassword(password);
        accountPassword.setScore(0);
        accountPassword.setStrength(PasswordStrength.MEDIUM);
        accountPassword=dao.save(accountPassword).getResult();
        AccountPasswordRecord accountPasswordRecord=new AccountPasswordRecord();
        BeanUtils.copyProperties(accountPassword,accountPasswordRecord,"id");
        dao.save(accountPasswordRecord);
        return true;
    }
}
